// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// s [author] rhyme_lph
// w [email]  rhymelph@gmail.com
// l [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/a.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/app_spaces.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/account_entity.dart';
import 'package:finance_app/src/entities/business_contact_entity.dart';
import 'package:finance_app/src/entities/debit_note_detail_entity.dart';
import 'package:finance_app/src/entities/invoice_entity.dart';
import 'package:finance_app/src/entities/ocr_attachment_entity.dart';
import 'package:finance_app/src/entities/payment_detail_entity.dart';
import 'package:finance_app/src/entities/payment_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';
import 'package:finance_app/src/entities/tax_submission_detail_entity.dart';
import 'package:finance_app/src/entities/transaction_entity.dart';
import 'package:finance_app/src/provider/dashboard/cash_in/new_cash_in_provider.dart';
import 'package:finance_app/src/provider/dashboard/sales/sales_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/router_gen/router_meta.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/object_utils.dart';
import 'package:finance_app/src/widgets/button/normal_popup_button.dart';
import 'package:finance_app/src/widgets/button/normal_text_button.dart';
import 'package:finance_app/src/widgets/common_app_bar.dart';
import 'package:finance_app/src/widgets/form/attach_file_form.dart';
import 'package:finance_app/src/widgets/form/form_edit_status_inherited_widget.dart';
import 'package:finance_app/src/widgets/form/icon_currency_price_input_form.dart';
import 'package:finance_app/src/widgets/form/text_area_input_form.dart';
import 'package:finance_app/src/widgets/form/value_select_form.dart';
import 'package:finance_app/src/widgets/input/form_input_field.dart';
import 'package:finance_app/src/widgets/select/normal_check_box.dart';
import 'package:finance_app/src/widgets/wrapper/normal_form_wrapper.dart';
import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart';

export 'package:finance_app/src/entities/payment_detail_entity.dart';

@RouterMeta(paramName: "newCashInPage")
class NewCashInPage extends StatefulWidget {
  final TransactionEntity data;
  final List<InvoiceEntity> invoiceList;
  final PaymentEntity paymentData;
  final bool isSelectMode;
  final BusinessContactEntity receiveFrom;
  final num total;
  final int assetId;
  final String assetNumber;
  final String assetName;
  final SettingDataCategory category;
  final SettingDataCurrency currency;
  final PaymentDetailEntity detailData;
  final TaxSubmissionDetailEntity taxPeriod;
  final String type;
  final DebitNoteDetailEntity debitNote;

  const NewCashInPage(
      {Key key,
      this.data,
      this.detailData,
      this.isSelectMode,
      this.paymentData,
      this.receiveFrom,
      this.total,
      this.assetId,
      this.assetNumber,
      this.assetName,
      this.category,
      this.currency,
      this.invoiceList,
      this.type,
      this.taxPeriod,
      this.debitNote})
      : super(key: key);

  @override
  _NewCashInPageState createState() => _NewCashInPageState();
}

class _NewCashInPageState extends State<NewCashInPage>
    with PagePresenter<NewCashInPage, NewCashInProvider> {
  String get title {
    final sale =
        Providers.get<SalesProvider>(RouterGenProviders.salesPage, null);
    if (sale != null) {
      if (provider.isRecordPayment) {
        return S.current.paymentin;
      }
    }
    if (provider.isShowInvoice) {
      return S.current.paymentin;
    }
    return provider.data == null && pageStatus != PageStatus.loading
        ? S.current.new_money_in
        : (provider.isEdit == true
            ? S.current.edit_money_in
            : S.current.money_in);
  }

  Widget get rightButton => listBuilder<bool>(
        selector: (_, __) => __.isEdit == false && __.data != null,
        builder: (BuildContext context, bool value, Widget child) =>
            value ? _buildPopButton() : _buildSaveBtn(),
      );

  @override
  PreferredSizeWidget get appBar => getDefaultAppBar(
          titleWidget: listBuilder<Tuple3<PaymentDetailEntity, bool, bool>>(
            selector: (_, __) => Tuple3(__.data, __.isEdit, __.isRecordPayment),
            builder: (BuildContext context,
                    Tuple3<PaymentDetailEntity, bool, bool> value,
                    Widget child) =>
                Text(value.item3
                    ? (value.item1 != null
                        ? S.current.paymentin
                        : S.current.receive_payment)
                    : title),
          ),
          actions: [
            rightButton,
          ]);

  @override
  void initState() {
    if (widget.category != null) {
      provider.transactionPurpose = widget.category;
    }
    provider.isSelectMode = widget.isSelectMode;
    provider.unit = Config.defaultCurrency;
    // cash and bank
    provider.initCashBank();
    // bank reconciliation
    provider.initBankReconciliation();
    provider.init(widget.data?.transactionableId ?? widget.paymentData?.id);
    provider.initInvoice(
        widget.invoiceList, widget.receiveFrom, widget.total, widget.currency);
    provider.initDetailDate(widget.detailData);
    provider.taxPeriod = widget.taxPeriod;
    provider.initType(widget.type);
    provider.initDebitNote(widget.debitNote);
    provider.initBusinessContactDetail();
    provider.initSalesOfFixedAsset(
        widget.assetId, widget.assetNumber, widget.assetName);

    provider.initHideFromAndUnable();
    super.initState();
  }

  Widget _buildPopButton() => listBuilder<Tuple2<bool, List<String>>>(
        selector: (_, __) => Tuple2(__.isEdit == true, List.from(__.menuList)),
        builder: (BuildContext context, Tuple2<bool, List<String>> value,
                Widget child) =>
            value.item1 == true
                ? Container()
                : NormalMorePopupButton(
                    onSelect: provider.onSelectMenu,
                    menuList: provider.menuList,
                  ),
      );

  Widget _buildSaveBtn() {
    return listBuilder<bool>(
      selector: (_, __) => pageStatus != PageStatus.loading,
      builder: (BuildContext context, bool value, Widget child) => value == true
          ? NormalSaveTextButton(
              onTap: provider.onSave,
            )
          : Container(),
    );
  }

  @override
  Widget wrapperBody(Widget child) {
    return listBuilder<bool>(
      selector: (_, __) => __.isEdit == true || provider.id == null,
      builder: (BuildContext context, bool value, Widget child) =>
          FormEditStatusInheritedWidget(
        isEdit: value,
        child: child,
      ),
      child: child,
    );
  }

  @override
  Widget get buildWidget => ColoredBox(
        color: Colors.white,
        child: ListView(
          children: [
            listBuilder<Tuple2<String, bool>>(
              selector: (_, __) => Tuple2<String, bool>(__.unit?.key ?? "SGD",
                  __.unableFromList.contains(S.current.price)),
              builder: (BuildContext context, Tuple2<String, bool> value,
                      Widget child) =>
                  IconCurrencyPriceInputForm(
                controller: provider.priceController,
                focusNode: provider.priceFocusNode,
                currency: value.item1,
                enable: !value.item2,
                svgIconPath: A.assetsImagesDashboardAddCashIn,
                onChangeCurrency: provider.onChangeUnit,
              ),
            ),
            if (provider.addition(S.current.gst_rate))
              Visibility(
                  visible: Config.currentCompany.enableGst == 1,
                  child: listBuilder<String>(
                    selector: (_, __) => __.gstRate?.displayName,
                    builder:
                        (BuildContext context, String value, Widget child) =>
                            Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        ValueSelectForm(
                          onTap: provider.onSelectGstRate,
                          title: S.current.gst_rate,
                          value: value,
                        ),
                        FormStatusWidget(
                          enable: listBuilder<bool>(
                            selector: (_, __) => __.isCheckInclusive,
                            builder: (BuildContext context, bool value,
                                    Widget child) =>
                                PressedOpacityButton(
                              // onPressed: provider.onChangeInclusive,
                              onPressed: null,
                              child: Padding(
                                padding:
                                    const EdgeInsets.fromLTRB(35, 15, 0, 15),
                                child: NormalCheckBox(
                                  isSelect: value,
                                  isEnable: false,
                                  title: S.current.inclusive_of_tax,
                                  minWidth: getDp(140),
                                ),
                              ),
                            ),
                          ),
                          disable: Padding(
                            padding: const EdgeInsets.fromLTRB(35, 15, 0, 15),
                            child: NormalCheckBox(
                              isEnable: false,
                              isSelect: provider.isCheckInclusive,
                              title: S.current.inclusive_of_tax,
                              minWidth: getDp(140),
                            ),
                          ),
                        ),
                        AppSpaces.grayH05,
                      ],
                    ),
                  )),
            if (!provider.hideFormList.contains(S.current.transaction_purpose))
              listBuilder<String>(
                selector: (_, __) => __.transactionPurpose?.name,
                builder: (BuildContext context, String value, Widget child) =>
                    ValueSelectForm(
                  onTap: provider.unableFromList
                          .contains(S.current.transaction_purpose)
                      ? null
                      : provider.onChangeTransactionPurpose,
                  title: S.current.transaction_purpose,
                  value: value,
                ),
              ),
            listBuilder<bool>(
                selector: (_, __) => __.isShowGrant,
                builder: (BuildContext context, bool value, Widget child) =>
                    value == true ? child : Container(),
                child: listBuilder<String>(
                  selector: (_, __) => __.grant?.name,
                  builder: (BuildContext context, String value, Widget child) =>
                      ValueSelectForm(
                    onTap: provider.onChangeGrant,
                    title: S.current.grant,
                    value: value,
                  ),
                )),
            if (!provider.hideFormList.contains(S.current.received_from))
              listBuilder<Tuple3<bool, bool, bool>>(
                selector: (_, __) =>
                    Tuple3(__.isShowGst, __.isShowInvoice, __.isShowDebitNote),
                builder: (BuildContext context, Tuple3<bool, bool, bool> v,
                        Widget child) =>
                    v.item1 == true || v.item2 == true || v.item3 == true
                        ? listBuilder<String>(
                            selector: (_, __) => __.receiver?.name,
                            builder: (BuildContext context, String value,
                                    Widget child) =>
                                ValueSelectForm(
                              title: S.current.received_from,
                              value: v.item1 == true ? S.current.iras : value,
                              onTap: provider.unableFromList
                                          .contains(S.current.received_from) ||
                                      v.item1 == true
                                  ? null
                                  : provider.onChangeReceiver,
                            ),
                          )
                        : Container(),
              ),
            listBuilder<bool>(
              selector: (_, __) => __.isShowInvoice,
              builder: (BuildContext context, bool value, Widget child) =>
                  value == true
                      ? listBuilder<String>(
                          selector: (_, __) => __.invoiceNumbers == null ||
                                  __.invoiceNumbers.length == 0
                              ? null
                              : __.invoiceNumbers
                                  .map((e) => '${e.number}')
                                  .toList()
                                  .join(','),
                          builder: (BuildContext context, String value,
                                  Widget child) =>
                              ValueSelectForm(
                            title: S.current.invoice_number,
                            value: value,
                            onTap: provider.onChangeInvoiceNumber,
                          ),
                        )
                      : Container(),
            ),
            listBuilder<bool>(
              selector: (_, __) => __.isShowGst,
              builder: (BuildContext context, bool value, Widget child) =>
                  value == true
                      ? listBuilder<String>(
                          selector: (_, __) => __.taxPeriod == null
                              ? null
                              : '${DateTimeUtils.formatDateTimeString(__.taxPeriod.startDate)} - ${DateTimeUtils.formatDateTimeString(__.taxPeriod.endDate)}',
                          builder: (BuildContext context, String value,
                                  Widget child) =>
                              ValueSelectForm(
                            title: S.current.tax_period,
                            value: value,
                            onTap: provider.unableFromList
                                    .contains(S.current.tax_period)
                                ? null
                                : provider.onChangeTaxPeriod,
                          ),
                        )
                      : Container(),
            ),
            listBuilder<bool>(
              selector: (_, __) => __.isShowDebitNote,
              builder: (BuildContext context, bool value, Widget child) =>
                  value == true
                      ? listBuilder<String>(
                          selector: (_, __) => __.debitNoteNumber?.number,
                          builder: (BuildContext context, String value,
                                  Widget child) =>
                              ValueSelectForm(
                            title: S.current.debit_note_number,
                            value: value,
                            onTap: provider.unableFromList
                                    .contains(S.current.debit_note_number)
                                ? null
                                : provider.onChangeDebitNoteNumber,
                          ),
                        )
                      : Container(),
            ),
            listBuilder<bool>(
              selector: (_, __) => __.numberHasError,
              builder: (BuildContext context, bool value, Widget child) =>
                  FromInputField(
                controller: provider.cashInNumberController,
                focusNode: provider.cashInNumberFocusNode,
                tip: S.current.transaction_number,
                hasError: value,
              ),
            ),
            listBuilder<DateTime>(
              selector: (_, __) => __.date,
              builder: (BuildContext context, DateTime value, Widget child) =>
                  ValueSelectForm(
                title: S.current.transaction_date,
                value: ObjectUtils.isNullDefaultFormat<DateTime>(value, null,
                    (data) => DateTimeUtils.formatGlobalDateTime(data)),
                onTap: provider.onChangeTransactionDate,
              ),
            ),
            listBuilder<String>(
              selector: (_, __) => __.transactionMethod?.name,
              builder: (BuildContext context, String value, Widget child) =>
                  ValueSelectForm(
                title: S.current.payment_method,
                value: value,
                onTap: provider.onChangeTransactionMethod,
              ),
            ),
            listBuilder<String>(
              selector: (_, __) => __.bankAccount?.bankName == null
                  ? null
                  : '${__.bankAccount.bankName} ${__.bankAccount.accountNumber ?? ''}',
              builder: (BuildContext context, String value, Widget child) =>
                  ValueSelectForm(
                title: S.current.bank_account,
                value: value,
                onTap: provider.unableFromList.contains(S.current.bank_account)
                    ? null
                    : provider.onChangeBankAccount,
              ),
            ),
            listBuilder<bool>(
                selector: (_, __) =>
                    __.bankAccount != null &&
                    __.unit?.key != __.bankAccount?.currencyCode,
                builder: (BuildContext context, bool value, Widget child) =>
                    Visibility(visible: value, child: child),
                child: listBuilder<AccountEntity>(
                  selector: (_, __) => __.bankAccount,
                  builder: (BuildContext context, AccountEntity value,
                          Widget child) =>
                      IconCurrencyPriceInputForm(
                    controller: provider.otherPriceController,
                    focusNode: provider.otherPriceFocusNode,
                    currency: value.currencyCode,
                    svgIconPath: A.assetsImagesDashboardAddCashIn,
                    // onChangeCurrency: provider.onChangeUnit,
                  ),
                )),
            FromInputField(
              tip: S.current.cheque_transaction_numberoptional,
              controller: provider.chequeTransactionNumberController,
              focusNode: provider.chequeTransactionNumberFocusNode,
              border: null,
            ),
            AppSpaces.grayH6,
            TextAreaInputForm(
              title: S.current.memo_optional,
              controller: provider.notesController,
              focusNode: provider.notesFocusNode,
            ),
            NormalFormWrapper(
              child:
                  listBuilder<Tuple2<List<String>, List<OcrAttachmentEntity>>>(
                selector: (_, __) => Tuple2(
                    List.from(__.files), List.from(__.attachments ?? [])),
                builder: (BuildContext context,
                        Tuple2<List<String>, List<OcrAttachmentEntity>> value,
                        Widget child) =>
                    AttachFileForm(
                  onAdd: provider.onAddAttachment,
                  files: value.item1,
                  onSelectFile: provider.onSelectFile,
                  attachments: value.item2,
                  onSelectAttachment: provider.onSelectAttachment,
                ),
              ),
            ),
            AppSpaces.h40,
          ],
        ),
      );
}
